package com.natalia.excel.utils;

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.exception.ExcelAnalysisException;
import com.alibaba.excel.util.StringUtils;
import com.natalia.excel.constants.MessageConstants;
import lombok.extern.slf4j.Slf4j;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.groups.Default;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * excel 实体校验
 *
 * @Author yang
 **/
@Slf4j
public class EasyExcelValidaHelper {


    private EasyExcelValidaHelper() {
    }

    private static Validator validator = Validation.buildDefaultValidatorFactory().getValidator();

    public static <T> String validateEntity(T obj,Integer rowIndex){
        StringBuilder result = new StringBuilder();
        try {
            Set<ConstraintViolation<T>> set = validator.validate(obj, Default.class);
            if (set != null && !set.isEmpty()) {
                for (ConstraintViolation<T> cv : set) {
                    Field declaredField = obj.getClass().getDeclaredField(cv.getPropertyPath().toString());
                    ExcelProperty annotation = declaredField.getAnnotation(ExcelProperty.class);
                    result.append("上传失败:第{")
                            .append(rowIndex)
                            .append("}行")
                            .append("{")
                            .append(annotation.value()[0])
                            .append("}列")
                            .append(cv.getMessage());
                }
            }
            return result.toString();
        }catch (NoSuchFieldException e){
            log.error(e.getMessage());
        }
        return result.toString();
    }

    public static void invokeHeadMap(Map<Integer, String> headMap,Class clazz) {
        if (clazz != null) {
            try {
                Map<Integer, String> indexNameMap = getIndexNameMap(clazz);
                Set<Integer> keySet = indexNameMap.keySet();
                for (Integer key : keySet) {
                    if (StringUtils.isEmpty(headMap.get(key))) {
                        throw new ExcelAnalysisException(MessageUtils.message(MessageConstants.ERROR_EXCEL_PLEASE_FORMAT_EXCEL));
                    }
                    if (!headMap.get(key).equals(indexNameMap.get(key))) {
                        throw new ExcelAnalysisException(MessageUtils.message(MessageConstants.ERROR_EXCEL_PLEASE_FORMAT_EXCEL));
                    }
                }
            } catch (NoSuchFieldException e) {
                log.info("Error parsing data{}", e.getMessage());
            }
        }
    }

    public static Map<Integer, String> getIndexNameMap(Class clazz) throws NoSuchFieldException {
        Map<Integer, String> result = new HashMap<>(2 << 3);
        Field field;
        Field[] fields = clazz.getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            field = clazz.getDeclaredField(fields[i].getName());
            field.setAccessible(true);
            ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
            if (excelProperty != null) {
                int index = excelProperty.index();
                String[] values = excelProperty.value();
                StringBuilder value = new StringBuilder();
                for (String v : values) {
                    value.append(v);
                }
                result.put(index, value.toString());
            }
        }
        return result;
    }
}
